package com.xxl.job.core.handler;

import com.xxl.job.core.biz.impl.ExecutorBizImpl;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.biz.model.TriggerParam;
import com.xxl.job.core.executor.XxlJobExecutor;
import com.xxl.job.core.glue.GlueFactory;
import com.xxl.job.core.glue.GlueTypeEnum;
import com.xxl.job.core.handler.impl.GlueJobHandler;
import com.xxl.job.core.handler.impl.ScriptJobHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author fanchunshuai
 * @Description
 * @Date 2023/3/3
 * @Version 1.0
 */
public class JobHandlerFactory {
    private static Logger logger = LoggerFactory.getLogger(JobHandlerFactory.class);


    /**
     * 创建glueJobHandler
     * @param triggerParam
     * @return
     */
    private IJobHandler createGlueJobHandler(TriggerParam triggerParam){
        try {
            IJobHandler originJobHandler = GlueFactory.getInstance().loadNewInstance(triggerParam.getGlueSource());
            IJobHandler jobHandler = new GlueJobHandler(originJobHandler, triggerParam.getGlueUpdatetime());
            return jobHandler;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        return null;
    }

    /**
     * 获取jobHandler
     * @param triggerParam
     * @return
     */
    public ReturnT<IJobHandler> getJobHandler(TriggerParam triggerParam){
        // valid：jobHandler + jobThread
        GlueTypeEnum glueTypeEnum = GlueTypeEnum.match(triggerParam.getGlueType());
        IJobHandler jobHandler = XxlJobExecutor.loadJobHandler(triggerParam.getExecutorHandler());

        if (GlueTypeEnum.BEAN == glueTypeEnum) {
            // jobHandler
            // valid handler
            if (jobHandler == null) {
                return new ReturnT<>(ReturnT.FAIL_CODE, "job handler [" + triggerParam.getExecutorHandler() + "] not found.");
            }

        } else if (GlueTypeEnum.GLUE_GROOVY == glueTypeEnum) {

            if(jobHandler == null || ((GlueJobHandler) jobHandler).getGlueUpdatetime() < triggerParam.getGlueUpdatetime()){
                jobHandler = createGlueJobHandler(triggerParam);
            }

            if(jobHandler == null){
                return new ReturnT<>(ReturnT.FAIL_CODE, "create GLUE_GROOVY failed");
            }
            XxlJobExecutor.registJobHandler(triggerParam.getExecutorHandler(), jobHandler);

        } else if (glueTypeEnum != null && glueTypeEnum.isScript()) {
            if(jobHandler == null || ((ScriptJobHandler) jobHandler).getGlueUpdatetime() < triggerParam.getGlueUpdatetime()){
                jobHandler = new ScriptJobHandler(triggerParam.getJobId(), triggerParam.getGlueUpdatetime(), triggerParam.getGlueSource(), GlueTypeEnum.match(triggerParam.getGlueType()));
            }
            XxlJobExecutor.registJobHandler(triggerParam.getExecutorHandler(), jobHandler);

        } else {
            return new ReturnT<>(ReturnT.FAIL_CODE, "glueType[" + triggerParam.getGlueType() + "] is not valid.");
        }

        return new ReturnT<>(jobHandler);

    }
}
